#include "ScriptInnerType.h"

#include <cassert>

#include "Reflection/Type.h"
#include "Reflection/NullObjectPtr.h"
#include "Object/Object.h"

bool WH::IsNumberType(EScriptInnerType InType)
{
    switch (InType)
    {
        case EScriptInnerType::Float:
        case EScriptInnerType::Double:
        case EScriptInnerType::Decimal:
        case EScriptInnerType::Int8:
        case EScriptInnerType::Uint8:
        case EScriptInnerType::Int16:
        case EScriptInnerType::Uint16:
        case EScriptInnerType::Int32:
        case EScriptInnerType::Uint32:
        case EScriptInnerType::Int64:
        case EScriptInnerType::Uint64:
            return true;
        default:
            return false;
    }
}

EScriptInnerType GetWiderNumberType(EScriptInnerType InType1, EScriptInnerType InType2)
{
    assert(WH::IsNumberType(InType1) && WH::IsNumberType(InType2));

    if(InType1> InType2)
    {
        return InType1;
    }
    else
    {
        return InType2;
    } 
}

CType *GetNativeType(EScriptInnerType InType)
{
    switch (InType)
    {
        case EScriptInnerType::Object:
            return RObject::StaticClass();

        case EScriptInnerType::String:
            return CGetType<CString>()();
        case EScriptInnerType::NullObject:
            return CNullObjectPtr::GetType();
        case EScriptInnerType::NullPtr:
            return CGetType<std::nullptr_t>()();
        case EScriptInnerType::Char:
            return CGetType<char32_t>()();
        case EScriptInnerType::Void:
            return CGetType<void>()();
        
        case EScriptInnerType::Bool:
            return CGetType<bool>()();
        
        case EScriptInnerType::Float:
            return CGetType<float>()();
        case EScriptInnerType::Double:
            return CGetType<double>()();
        case EScriptInnerType::Int32:
            return CGetType<int32_t>()();
        case EScriptInnerType::Uint32:
            return CGetType<uint32_t>()();
        case EScriptInnerType::Int64:
            return CGetType<int64_t>()();
        case EScriptInnerType::Uint64:
            return CGetType<uint64_t>()();
        case EScriptInnerType::Int16:
            return CGetType<int16_t>()();
        case EScriptInnerType::Uint16:
            return CGetType<uint16_t>()();
        case EScriptInnerType::Int8:
            return CGetType<int8_t>()();
        case EScriptInnerType::Uint8:
            return CGetType<uint8_t>()();

        default:
            assert(false && "not implemented");
            return nullptr;
    }
}
